#include "od_sip_timer.h"
#include "od_errno.h"


int od_sip_timer_process_req(od_sip_ctx *ctx, eXosip_event_t *event)
{
    osip_header_t *dest = NULL;
    
    OD_SIP_ASSERT(ctx && event);

    if (MSG_IS_UPDATE(event->request)) {
        if (osip_message_header_get_byname(event->request, Session_Expires, 0, &dest) < 0
             && osip_message_header_get_byname(event->request, SHORT_SE, 0, &dest) < 0) {
            ctx->share->se_timer.refresher = RFH_UNSUPPORT;
        }else {
            if (dest->hvalue) {
                char *ptr = NULL;
                if ((ptr = strstr(dest->hvalue, "refresher")) == NULL) {
                    ctx->share->se_timer.sess_expires = atoi(dest->hvalue);
                }else {
                    char buf[32] = {0};
                    sscanf(dest->hvalue, "%[^;]",buf);
                    ctx->share->se_timer.sess_expires = atoi(buf);
                }
            }
        }
    }else if (MSG_IS_INVITE(event->request)) {
        /*parse event->request,get Min-SE*/
        if (osip_message_header_get_byname(event->request, Min_SE, 0, &dest) < 0) {
                RPTWRN("Found no Min_SE in this response header!!");
        }else {
            if (dest->hvalue) {
                ctx->share->se_timer.min_se = atoi(dest->hvalue);
                RPTWRN("422 Min_se:%d", ctx->share->se_timer.min_se);
            }
        }

        if (osip_message_header_get_byname(event->request, Session_Expires, 0, &dest) < 0
             && osip_message_header_get_byname(event->request, SHORT_SE, 0, &dest) < 0) {
            ctx->share->se_timer.refresher = RFH_UNSUPPORT;
        }else {
            if (dest->hvalue) {
                char *ptr = NULL;
                if ((ptr = strstr(dest->hvalue, "refresher")) == NULL) {
                    ctx->share->se_timer.sess_expires = atoi(dest->hvalue);
                    ctx->share->se_timer.refresher = RFH_UNKNOWN;
                }else {
                    char buf[32] = {0};
                    sscanf(dest->hvalue, "%[^;]",buf);
                    ctx->share->se_timer.sess_expires = atoi(buf);
                    memset(buf, 0, sizeof(buf));
                    sscanf(ptr, "refresher=%s", buf);
                    if (!strcasecmp(buf, "uac"))
                        ctx->share->se_timer.refresher = RFH_UAC;
                    else if (!strcasecmp(buf, "uas"))
                        ctx->share->se_timer.refresher = RFH_UAS;
                    else 
                        ctx->share->se_timer.refresher = RFH_UNKNOWN;
                }

                if (ctx->share->se_timer.sess_expires < 90) {
                    ctx->share->se_timer.min_se = 90;
                    RPTERR("sesson_expires < 90, error!!");
                    return OD_ERROR;
                }else if (ctx->share->se_timer.sess_expires < ctx->share->se_timer.min_se) {
                    RPTERR("sesson_expires:[%d] < min_se:[%d], error!!", 
                        ctx->share->se_timer.sess_expires, ctx->share->se_timer.min_se);
                    return OD_ERROR;
                }
            }
        }
    }

    RPTDBG("Session-Expires:%d, Min-SE:%d, refresher:%d", 
            ctx->share->se_timer.sess_expires,
            ctx->share->se_timer.min_se,
            ctx->share->se_timer.refresher);

    return OD_OK;
}

int od_sip_timer_process_resp(od_sip_ctx *ctx, eXosip_event_t *event)
{
    osip_header_t *dest = NULL;
    
    OD_SIP_ASSERT_RETURN(ctx && event, OD_ERROR);
    
    /*parse event->response,get Min-SE*/
    if (osip_message_header_get_byname(event->response, Min_SE, 0, &dest) < 0) {
        if (event->response->status_code == SIP_SESSION_TIMER_TOO_SMALL) {
            RPTERR("Response is 422, but found no Min_SE in this response header!!");
        }
    }else {
        if (dest->hvalue) {
            ctx->share->se_timer.min_se = atoi(dest->hvalue);
            RPTWRN("422 Min_se:%d", ctx->share->se_timer.min_se);
        }
    }

    if (osip_message_header_get_byname(event->response, Session_Expires, 0, &dest) < 0
         && osip_message_header_get_byname(event->response, SHORT_SE, 0, &dest) < 0) {
        ctx->share->se_timer.refresher = RFH_UNSUPPORT;
    }else {
        if (dest->hvalue) {
            char *ptr = NULL;
            if ((ptr = strstr(dest->hvalue, "refresher")) == NULL) {
                ctx->share->se_timer.sess_expires = atoi(dest->hvalue);
                ctx->share->se_timer.refresher = RFH_UNKNOWN;
            }else {
                char buf[32] = {0};
                sscanf(dest->hvalue, "%[^;]",buf);
                ctx->share->se_timer.sess_expires = atoi(buf);
                memset(buf, 0, sizeof(buf));
                sscanf(ptr, "refresher=%s", buf);
                if (!strcasecmp(buf, "uac"))
                    ctx->share->se_timer.refresher = RFH_UAC;
                else if (!strcasecmp(buf, "uas"))
                    ctx->share->se_timer.refresher = RFH_UAS;
                else 
                    ctx->share->se_timer.refresher = RFH_UNKNOWN;
            }
        }
    }

    RPTDBG("Session-Expires:%d, Min-SE:%d, refresher:%d", 
            ctx->share->se_timer.sess_expires,
            ctx->share->se_timer.min_se,
            ctx->share->se_timer.refresher);

    return OD_OK;
}


void od_sip_timer_create_update_req(od_sip_ctx *ctx, int did) 
{
    osip_message_t *request = NULL;
    char buf[64] = {0};
    
    OD_SIP_ASSERT(ctx);
    
    eXosip_lock(ctx->ex_ctx);
    eXosip_call_build_update(ctx->ex_ctx, did, &request);
    if (ctx->share->se_timer.refresher == RFH_UAC) 
        snprintf(buf, sizeof(buf), "%d;refreaher=uac", ctx->share->se_timer.sess_expires);
    else if (ctx->share->se_timer.refresher == RFH_UAS)
        snprintf(buf, sizeof(buf), "%d;refreaher=uas", ctx->share->se_timer.sess_expires);
    else
        snprintf(buf, sizeof(buf), "%d", ctx->share->se_timer.sess_expires);
    osip_message_set_header(request, Session_Expires, buf);
    eXosip_call_send_request(ctx->ex_ctx, did, request);
    eXosip_unlock(ctx->ex_ctx);
}


/*_*/

